home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: TS3Sound.c
- *
- * Contents: Handles some of the sound stuff.
- *
- * Copyright © 1996 Apple Computer, Inc.
- */
-
- #include <assert.h>
- #include <math.h>
- #include <stdio.h>
- #include <string.h>
-
- #include <Components.h>
- #include <Controls.h>
- #include <Dialogs.h>
- #include <Sound.h>
- #include <SoundComponents.h>
- #include <Resources.h>
- #include <Timer.h>
- #include <ToolUtils.h>
- #include <Types.h>
-
- #define __USING_OLD_SOUND_H__ 0
- #include "SoundSprocket.h"
-
- #include "TS3Message.h"
- #include "TS3Resource.h"
- #include "TS3Sound.h"
- #include "TS3Utils.h"
- #include "TS3Window.h"
-
- static SndChannelPtr gSoundChannel = NULL;
- static SndListHandle gSoundResource = NULL;
- static DialogPtr gSoundDialog = NULL;
- static SSpLocalizationData gSoundPrev3DInfo;
-
-
- static Boolean CheckVersionNumber(
- const NumVersion* inVersion,
- UInt8 inMajor,
- UInt8 inMinor,
- UInt8 inBug);
-
- static WindowMethodPtr Sound_MetaHandler(
- WindowMethod inMethod);
-
- static void Sound_ConsumeEvent(
- WindowPtr inWindow,
- const EventRecord* inEvent,
- Boolean* outConsumed);
-
- static void Sound_Update(
- WindowPtr inWindow);
-
- static Boolean EventProc(
- EventRecord *inEvent);
-
- static pascal void Sound_BoxUserItem(
- DialogPtr inDialog,
- short inItem);
-
-
- /*******************************************************************************
- * CheckVersionNumber
- *
- * Returns true if the given version number is compatible with (i. e not older
- * than) version inMajor.inMinor.inBug.
- ******************************************************************************/
- Boolean CheckVersionNumber(
- const NumVersion* inVersion,
- UInt8 inMajor,
- UInt8 inMinor,
- UInt8 inBug)
- {
- if (inVersion->majorRev != inMajor)
- {
- return inVersion->majorRev > inMajor;
- }
- else
- {
- return inVersion->minorAndBugRev >= inMinor << 4 | inBug;
- }
- }
-
-
- // **************************** GetSSpFilterVersion ****************************
- // Finds the manufacturer and version number of the SoundSprocket filter that
- // may be installed. inManufacturer should be the manufacturer code specified
- // at the installation time, which may be zero to allow any manufacturer.
- // If no error is encountered, outManufacturer is set to the actual manufacturer
- // code and outMajorVersion and outMinorVersion are set to the component
- // specification level and manufacturer's implementation revision, respectively.
- static OSStatus GetSSpFilterVersion(
- OSType inManufacturer,
- OSType* outManufacturer,
- UInt32* outMajorVersion,
- UInt32* outMinorVersion)
- {
- OSStatus err;
- ComponentDescription description;
- Component componentRef;
- UInt32 vers;
-
- // Set up the component description
- description.componentType = kSoundEffectsType;
- description.componentSubType = kSSpLocalizationSubType;
- description.componentManufacturer = inManufacturer;
- description.componentFlags = 0;
- description.componentFlagsMask = 0;
-
- // Find a component matching the description
- componentRef = FindNextComponent(nil, &description);
- if (componentRef == nil) return couldntGetRequiredComponent;
-
- // Get the component description (for the manufacturer code)
- err = GetComponentInfo(componentRef, &description, nil, nil, nil);
- if (err != noErr) return err;
-
- // Get the version composite
- vers = (UInt32) GetComponentVersion((ComponentInstance) componentRef);
-
- // Return the results
- *outManufacturer = description.componentManufacturer;
- *outMajorVersion = HiWord(vers);
- *outMinorVersion = LoWord(vers);
-
- return noErr;
- }
-
-
- /* =============================================================================
- * Sound_Init (external)
- *
- * Initializes the sound stuff.
- * ========================================================================== */
- void Sound_Init(
- void)
- {
- OSStatus err;
- SoundComponentLink link;
- NumVersion version;
- OSType manufacturer;
- UInt32 majorVersion;
- UInt32 minorVersion;
-
- assert(kFeedbackItem_COUNT == kFeedbackItem_ExpectedCount);
-
- // Check the sound manager version
- version = SndSoundManagerVersion(); //••• WARNING •••
- //• IF YOU CAN'T COMPILE THE PREVIOUS LINE, YOU MUST UPGRADE TO ETO #20 OR
- //• EDIT YOUR Sound.h TO MAKE SndSoundManagerVersion RETURN THE TYPE NumVersion.
-
- if (!CheckVersionNumber(&version, 3, 2, 1))
- {
- StopAlert(kAlrtID_SoundMgrVersion, NULL);
- // Note: A normal application would bail on 3D sound here
- }
-
- // Allocate the sound channel
- err = SndNewChannel(&gSoundChannel, sampledSynth, initMono, NULL);
- Message_CheckError(err, "Sound_Init", "SndNewChannel");
-
- assert(gSoundChannel != NULL);
-
- // Install the 3D sound filters
- link.description.componentType = kSoundEffectsType;
- link.description.componentSubType = kSSpLocalizationSubType;
- link.description.componentManufacturer = 0;
- link.description.componentFlags = 0;
- link.description.componentFlagsMask = 0;
- link.mixerID = nil;
- link.linkID = nil;
-
- SndSetInfo(gSoundChannel, siPreMixerSoundComponent, &link);
- Message_CheckError(err, "Sound_Init", "SndNewChannel");
-
- // Verify that the right version filter was installed
- err = GetSSpFilterVersion(
- link.description.componentManufacturer,
- &manufacturer,
- &majorVersion,
- &minorVersion);
-
- if (err != noErr)
- {
- // Filter must not be installed
- // Note: A normal application would bail on 3D sound here
- StopAlert(kAlrtID_FilterNotInstalled, NULL);
- }
- else
- {
- // The major version represents the component specification level
- if (majorVersion < 1)
- {
- //• if we couldn't handle some old version, we could bail here.
-
- StopAlert(kAlrtID_FilterVersion, NULL);
- // Note: A normal application would bail on 3D sound here
- }
- else
- {
- // The minor version specifies the manufacturer's implementation revision
-
- //• could do something here is we needed to handle tweaks for specific
- //• manufacturers or versions.
- }
- }
-
- // Grab the dialog
- gSoundDialog = GetNewDialog(kDlogID_Feedback, NULL, (WindowPtr) -1);
- assert(gSoundDialog != NULL);
-
- // Set up our method table
- Window_New(gSoundDialog, Sound_MetaHandler);
-
- // Show the dialog
- ShowWindow(gSoundDialog);
-
- // Initialize the SSpLocalizationData state to garbage
- memset(&gSoundPrev3DInfo, 0x55, sizeof(SSpLocalizationData));
- }
-
-
- /* =============================================================================
- * Sound_Exit (external)
- *
- * Prepares for exit.
- * ========================================================================== */
- void Sound_Exit(
- void)
- {
- Sound_PlaySilence();
- assert(gSoundResource == NULL);
-
- if (gSoundChannel != NULL)
- {
- SndDisposeChannel(gSoundChannel, true);
- gSoundChannel = NULL;
- }
-
- if (gSoundDialog != NULL)
- {
- DisposeDialog(gSoundDialog);
- gSoundDialog = NULL;
- }
- }
-
-
- /* =============================================================================
- * Sound_MetaHandler (internal)
- *
- * Returns the method function pointer that corresponds to the given ID.
- * ========================================================================== */
- WindowMethodPtr Sound_MetaHandler(
- WindowMethod inMethod)
- {
- WindowMethodPtr result;
-
- result = NULL;
-
- switch (inMethod)
- {
- case kWindowMethod_ConsumeEvent:
- result = (WindowMethodPtr) Sound_ConsumeEvent;
- break;
-
- case kWindowMethod_Update:
- result = (WindowMethodPtr) Sound_Update;
- break;
- }
-
- return result;
- }
-
-
- /* =============================================================================
- * Sound_ConsumeEvent (internal)
- *
- * Called for each event when this is the front window.
- * ========================================================================== */
- void Sound_ConsumeEvent(
- WindowPtr inWindow,
- const EventRecord* inEvent,
- Boolean* outConsumed)
- {
- #pragma unused (inWindow)
- Boolean consumed;
- WindowPtr window;
- short item;
-
- assert(inEvent != NULL);
- assert(outConsumed != NULL);
-
- consumed = false;
-
- if (inEvent->what == activateEvt)
- {
- // We need to look at the activate event here because it is
- // consumed by IsDialogEvent/DialogSelect below and so never
- // gets to the window stuff
- window = (WindowPtr) inEvent->message;
-
- if (inEvent->modifiers & activeFlag)
- {
- Window_Activate(window);
- }
- else
- {
- Window_Deactivate(window);
- }
- }
-
- // Do dialog stuff
- if (inEvent->what != keyDown || (inEvent->modifiers & cmdKey) == 0)
- {
- consumed = IsDialogEvent(inEvent);
- if (consumed)
- {
- DialogSelect(inEvent, &window, &item);
- }
- }
-
- // Return the result
- *outConsumed = consumed;
- }
-
-
- /* =============================================================================
- * Sound_Update (internal)
- *
- * Updates the contents of the window.
- * ========================================================================== */
- void Sound_Update(
- WindowPtr inWindow)
- {
- DrawDialog(inWindow);
- }
-
-
- /* =============================================================================
- * Sound_Configure (external)
- *
- * Stops the current sound, puts up the Configure dialog box, and resumes the
- * stopped sound.
- * ========================================================================== */
- void Sound_Configure(
- void)
- {
- OSStatus err;
- Boolean playing;
- short resID;
- ResType resType;
- Str255 resName;
-
- // Find out which sound to restore
- playing = gSoundResource != NULL;
-
- if (playing)
- {
- GetResInfo((Handle) gSoundResource, &resID, &resType, resName);
- }
-
- // Quiet
- Sound_PlaySilence();
-
- // Configure
- err = SSpConfigureSpeakerSetup(EventProc);
- Message_CheckError(err, "Sound_Configure", "SSpConfigureSpeakerSetup");
-
- // Play it again, Sam
- if (playing)
- {
- Sound_PlayResource(resName);
- }
- }
-
-
- /* =============================================================================
- * EventProc (internal)
- *
- * Called to process events during the 3D sound Configure dialog. Returns
- * true if the event was handled (except for update events).
- * ========================================================================== */
- Boolean EventProc(
- EventRecord *inEvent)
- {
- WindowPtr wind;
-
- assert(inEvent != NULL);
-
- if (inEvent->what == updateEvt)
- {
- wind = (WindowPtr) inEvent->message;
-
- if (Window_IsMine(wind))
- {
- SetPort(wind);
- BeginUpdate(wind);
- Window_Update(wind);
- EndUpdate(wind);
- }
- }
-
- return false;
- }
-
-
- /* =============================================================================
- * Sound_PlaySilence (external)
- *
- * Stops any sound that is playing.
- * ========================================================================== */
- void Sound_PlaySilence(
- void)
- {
- OSStatus err;
- SndCommand sndCommand;
-
- sndCommand.cmd = quietCmd;
- sndCommand.param1 = 0;
- sndCommand.param2 = 0;
- err = SndDoImmediate(gSoundChannel, &sndCommand);
- Message_CheckError(err, "Sound_PlaySilence", "SndDoImmediate");
-
- if (gSoundResource != NULL)
- {
- ReleaseResource((Handle) gSoundResource);
- gSoundResource = NULL;
- }
- }
-
-
- /* =============================================================================
- * Sound_PlayResource (external)
- *
- * Plays the 'snd ' resource that has the given name. Returns true if
- * successful; returns false if unsuccessful and therefore silence is happening.
- * ========================================================================== */
- Boolean Sound_PlayResource(
- Str255 inSndName)
- {
- OSStatus err;
- SndCommand sndCommand;
- long offset;
-
- // Silence the sound channel and get rid of the old resource
- Sound_PlaySilence();
-
- // Grab the resource
- gSoundResource = (SndListHandle) GetNamedResource('snd ', inSndName);
- if (gSoundResource == NULL || ResError() != noErr)
- {
- StopAlert(kAlrtID_BadSndLoad, NULL);
- goto bail;
- }
-
- // Lock it down
- HLockHi((Handle) gSoundResource);
-
- // Play it indefinitely
- GetSoundHeaderOffset(gSoundResource, &offset);
-
- sndCommand.cmd = soundCmd;
- sndCommand.param1 = 0;
- sndCommand.param2 = (long) *gSoundResource + offset;
- err = SndDoImmediate(gSoundChannel, &sndCommand);
- Message_CheckError(err, "Sound_PlayResource", "SndDoImmediate");
-
- sndCommand.cmd = freqCmd;
- sndCommand.param1 = 0;
- sndCommand.param2 = 60;
- err = SndDoImmediate(gSoundChannel, &sndCommand);
- Message_CheckError(err, "Sound_PlayResource", "SndDoImmediate");
-
- return true;
-
- // Error exit
- bail:
- if (gSoundResource != NULL)
- {
- ReleaseResource((Handle) gSoundResource);
- gSoundResource = NULL;
- }
-
- return false;
- }
-
-
- /* =============================================================================
- * Sound_Set3DInfo (external)
- *
- * Sends the given 3D info to the sound channel.
- * ========================================================================== */
- void Sound_Set3DInfo(
- const SSpLocalizationData* in3DInfo)
- {
- OSStatus err;
- Str255 str;
- UnsignedWide time;
-
- static UnsignedWide prevTime = {0, 0};
-
- assert(in3DInfo != NULL);
-
- // Change the filter
- err = SndSetInfo(gSoundChannel, siSSpLocalization, (SSpLocalizationData*) in3DInfo);
- Message_CheckError(err, "Sound_Set3DInfo", "SndSetInfo");
-
- // Update the dialog
- Microseconds(&time);
-
- Utils_SetUInt32Field(
- gSoundDialog,
- kFeedbackItem_Updates,
- 1000000.0 / (time.lo-prevTime.lo),
- true);
-
- prevTime = time;
-
- if (gSoundPrev3DInfo.cpuLoad != in3DInfo->cpuLoad)
- {
- Utils_SetUInt32Field(
- gSoundDialog,
- kFeedbackItem_CPULoad,
- in3DInfo->cpuLoad,
- true);
-
- gSoundPrev3DInfo.cpuLoad = in3DInfo->cpuLoad;
- }
-
- if (gSoundPrev3DInfo.medium != in3DInfo->medium)
- {
- switch (in3DInfo->medium)
- {
- case kSSpMedium_Air:
- strcpy((char*) str, (char*) "\pkSSp…Air");
- break;
-
- case kSSpMedium_Water:
- strcpy((char*) str, (char*) "\pkSSp…Water");
- break;
-
- default:
- sprintf((char*) str, "x<<%lu>>", (unsigned long) in3DInfo->medium);
- str[0] = strlen((char*) str) - 1;
- }
-
- Utils_SetStr255Field(
- gSoundDialog,
- kFeedbackItem_Medium,
- str,
- true);
-
- gSoundPrev3DInfo.medium = in3DInfo->medium;
- }
-
- if (gSoundPrev3DInfo.humidity != in3DInfo->humidity)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_Humidity,
- in3DInfo->humidity,
- true);
-
- gSoundPrev3DInfo.humidity = in3DInfo->humidity;
- }
-
- if (gSoundPrev3DInfo.roomSize != in3DInfo->roomSize)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_RoomSize,
- in3DInfo->roomSize,
- true);
-
- gSoundPrev3DInfo.roomSize = in3DInfo->roomSize;
- }
-
- if (gSoundPrev3DInfo.roomReflectivity != in3DInfo->roomReflectivity)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_RoomReflectivity,
- in3DInfo->roomReflectivity,
- true);
-
- gSoundPrev3DInfo.roomReflectivity = in3DInfo->roomReflectivity;
- }
-
- if (gSoundPrev3DInfo.reverbAttenuation != in3DInfo->reverbAttenuation)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_ReverbAttenuation,
- in3DInfo->reverbAttenuation,
- true);
-
- gSoundPrev3DInfo.reverbAttenuation = in3DInfo->reverbAttenuation;
- }
-
- if (gSoundPrev3DInfo.sourceMode != in3DInfo->sourceMode)
- {
- switch (in3DInfo->sourceMode)
- {
- case kSSpSourceMode_Unfiltered:
- strcpy((char*) str, (char*) "\pkSSp…Unfiltered");
- break;
-
- case kSSpSourceMode_Localized:
- strcpy((char*) str, (char*) "\pkSSp…Localized");
- break;
-
- case kSSpSourceMode_Ambient:
- strcpy((char*) str, (char*) "\pkSSp…Ambient");
- break;
-
- case kSSpSourceMode_Binaural:
- strcpy((char*) str, (char*) "\pkSSp…Binaural");
- break;
-
- default:
- sprintf((char*) str, "x<<%lu>>", (unsigned long) in3DInfo->sourceMode);
- str[0] = strlen((char*) str) - 1;
- }
-
- Utils_SetStr255Field(
- gSoundDialog,
- kFeedbackItem_SourceMode,
- str,
- true);
-
- gSoundPrev3DInfo.sourceMode = in3DInfo->sourceMode;
- }
-
- if (gSoundPrev3DInfo.referenceDistance != in3DInfo->referenceDistance)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_ReferenceDistance,
- in3DInfo->referenceDistance,
- true);
-
- gSoundPrev3DInfo.referenceDistance = in3DInfo->referenceDistance;
- }
-
- if (gSoundPrev3DInfo.coneAngleCos != in3DInfo->coneAngleCos)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_ConeAngleCos,
- in3DInfo->coneAngleCos,
- true);
-
- gSoundPrev3DInfo.coneAngleCos = in3DInfo->coneAngleCos;
- }
-
- if (gSoundPrev3DInfo.coneAttenuation != in3DInfo->coneAttenuation)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_ConeAttenuation,
- in3DInfo->coneAttenuation,
- true);
-
- gSoundPrev3DInfo.coneAttenuation = in3DInfo->coneAttenuation;
- }
-
- if (gSoundPrev3DInfo.currentLocation.elevation != in3DInfo->currentLocation.elevation)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_Elevation,
- in3DInfo->currentLocation.elevation,
- true);
-
- gSoundPrev3DInfo.currentLocation.elevation = in3DInfo->currentLocation.elevation;
- }
-
- if (gSoundPrev3DInfo.currentLocation.azimuth != in3DInfo->currentLocation.azimuth)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_Azimuth,
- in3DInfo->currentLocation.azimuth,
- true);
-
- gSoundPrev3DInfo.currentLocation.azimuth = in3DInfo->currentLocation.azimuth;
- }
-
- if (gSoundPrev3DInfo.currentLocation.distance != in3DInfo->currentLocation.distance)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_Distance,
- in3DInfo->currentLocation.distance,
- true);
-
- gSoundPrev3DInfo.currentLocation.distance = in3DInfo->currentLocation.distance;
- }
-
- if (gSoundPrev3DInfo.currentLocation.projectionAngle != in3DInfo->currentLocation.projectionAngle)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_ProjectionAngle,
- in3DInfo->currentLocation.projectionAngle,
- true);
-
- gSoundPrev3DInfo.currentLocation.projectionAngle = in3DInfo->currentLocation.projectionAngle;
- }
-
- if (gSoundPrev3DInfo.currentLocation.sourceVelocity != in3DInfo->currentLocation.sourceVelocity)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_SourceVelocity,
- in3DInfo->currentLocation.sourceVelocity,
- true);
-
- gSoundPrev3DInfo.currentLocation.sourceVelocity = in3DInfo->currentLocation.sourceVelocity;
- }
-
- if (gSoundPrev3DInfo.currentLocation.listenerVelocity != in3DInfo->currentLocation.listenerVelocity)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_ListenerVelocity,
- in3DInfo->currentLocation.listenerVelocity,
- true);
-
- gSoundPrev3DInfo.currentLocation.listenerVelocity = in3DInfo->currentLocation.listenerVelocity;
- }
-
- if (gSoundPrev3DInfo.reserved0 != in3DInfo->reserved0)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_Reserved0,
- in3DInfo->reserved0,
- true);
-
- gSoundPrev3DInfo.reserved0 = in3DInfo->reserved0;
- }
-
- if (gSoundPrev3DInfo.reserved1 != in3DInfo->reserved1)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_Reserved1,
- in3DInfo->reserved1,
- true);
-
- gSoundPrev3DInfo.reserved1 = in3DInfo->reserved1;
- }
-
- if (gSoundPrev3DInfo.reserved2 != in3DInfo->reserved2)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_Reserved2,
- in3DInfo->reserved2,
- true);
-
- gSoundPrev3DInfo.reserved2 = in3DInfo->reserved2;
- }
-
- if (gSoundPrev3DInfo.reserved3 != in3DInfo->reserved3)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_Reserved3,
- in3DInfo->reserved3,
- true);
-
- gSoundPrev3DInfo.reserved3 = in3DInfo->reserved3;
- }
-
- if (gSoundPrev3DInfo.virtualSourceCount != in3DInfo->virtualSourceCount)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_VirtualSourceCount,
- in3DInfo->virtualSourceCount,
- true);
-
- gSoundPrev3DInfo.virtualSourceCount = in3DInfo->virtualSourceCount;
- }
- }
-
-
-